package com.example.onlinemusic.controller;
import java.lang.Integer;

import com.example.onlinemusic.mapper.LoveMusicMapper;
import com.example.onlinemusic.tools.Constant;
import com.example.onlinemusic.mapper.MusicMapper;
import com.example.onlinemusic.model.Music;
import com.example.onlinemusic.model.User;
import com.example.onlinemusic.tools.Constant;
import com.example.onlinemusic.tools.ResponseBodyMessage;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.binding.BindingException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.ssl.SslProperties;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

//import static jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle.title;

//import static com.example.onlinemusic.tools.Constant.USERINFO_SESSION_KEY;

@RestController
@RequestMapping("/music")
public class MusicController {


    /*@Value("${music.local.path}")*/
//    @Value("/store")
//    private String SAVE_PATH;

    /*能用
    @Value("D:/myproject/onlinemusic/")
    private String SAVE_PATH;*/
//    @Value("${music.local.path}")
//    private String musicLocalPath;
    @Value("${store}")
    private String SAVE_PATH;
    @Autowired
    private MusicMapper musicMapper;
    @Autowired
    private LoveMusicMapper loveMusicMapper;

    //Integer ID  = new Integer;
    //private String SAVE_PATH = "D:/myproject/onlinemusic/";//注意，末尾这里要有一个/
    @RequestMapping("/upload")
    public ResponseBodyMessage<Boolean> insertMusic(@RequestParam String singer,
                                                    @RequestParam("filename") MultipartFile file,//这里，注解后边括号里的参数，要和前端的对应上
                                                    HttpServletRequest request,
                                                    HttpServletResponse response) throws IOException {//这里：需要验证是否已经登录了。登录了才能上传音乐——需要从session中获取这个数据
        //1.检查是否登录了
        HttpSession httpSession = request.getSession(false);
        if (httpSession == null || httpSession.getAttribute(Constant.USERINFO_SESSION_KEY) == null) {
            System.out.println("上传失败，用户尚未登录");
            return new ResponseBodyMessage<>(-1, "请先登录", false);
        }


        /*
        //优化！！！
        //防止重复上传
        */
        //先查询数据库中，是否有当前音乐【歌曲名+歌手】
        //根据前边获取的文件名来写
        String fileNameAndType = file.getOriginalFilename();//含后缀：***.mp3
        System.out.println("filename:" + fileNameAndType);//打印一个日志
        int index = fileNameAndType.lastIndexOf(".");//获取最后一个.的下标，它后面就是文件后缀——不需要的部分
        String title = fileNameAndType.substring(0, index);//左闭右开区间（这里可以复习一下一些常用函数~~~）
        Music music = musicMapper.seleltByTitleAndSinger(title, singer);
        if (music != null) {
            System.out.println("以经上传过这首了");
            return new ResponseBodyMessage<>(-1, "以经上传过这首了", false);
        }

        //2.上传到服务器
        // 登陆成功，获取当前上传音乐的完整的名字

//        String fileNameAndType = file.getOriginalFilename();//含后缀：***.mp3
//        System.out.println("filename:" + fileNameAndType);//打印一个日志

        String path = SAVE_PATH + fileNameAndType;
    //重新测试
        File dest = new File(path);//这里可以复习一下File类及方法
        System.out.println("--------------------"+path);
        System.out.println(dest.getAbsoluteFile());
        System.out.println();
        if (!dest.exists()) {//如果不存在，就创建
            dest.mkdirs();
        }

        try {
            file.transferTo(dest);
            //return new ResponseBodyMessage<>(0,"上传成功",true);
        } catch (IOException e) {
            //throw new RuntimeException(e);
            e.printStackTrace();
            return new ResponseBodyMessage<>(-1, "上传失败", false);
        }

        //return new ResponseBodyMessage<>(-1,"上传失败",false);

        //3.进行数据库的上传
        //（1）准备数据 （2）调用insert

//        //根据前边获取的文件名来写
//        int index = fileNameAndType.lastIndexOf(".");//获取最后一个.的下标，它后面就是文件后缀——不需要的部分
//        String title = fileNameAndType.substring(0, index);//左闭右开区间（这里可以复习一下一些常用函数~~~）
        //用户发送上传请求的时候，写过了
        // String singer;

        //根据session来写
        User user = (User) httpSession.getAttribute(Constant.USERINFO_SESSION_KEY);//这里要注意：导包的是咱们自己创建的类的……
        int userid = user.getId();

        //1.播放音乐-》http请求
        String url = "/music/get?path=" + title;//前边写死的部分，是给定这个请求一个相对路径，之后，再根据音乐名进行查找（拼接了音乐名）


        //2.获取时间（格式化）
        //SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");
        Date date = new Date();//其实这句可以直接写在time那句，作为参数
        String time = sf.format(date);


        try {
            int ret = 0;
            ret = musicMapper.insert(title, singer, time, url, userid);//SQL语句，insert操作返回的是影响的行数（一条数据，影响一行）
            if (ret == 1) {
                //这里应该跳转到音乐列表页面
                //补充上了：
                response.sendRedirect("/list.html");
                return new ResponseBodyMessage<>(0, "上传数据库成功", true);
            } else {
                return new ResponseBodyMessage<>(-1, "上传数据库失败", false);//注意，这里的else不能，因为，这里的上传到数据库失败，和insert方法异常，原因可能不是同一个~~~那么，这种如何处理服务器中的内容呢？？？
            }
        } catch (BindingException e) {

            e.printStackTrace();
            dest.delete();//删除服务器中的内容
            return new ResponseBodyMessage<>(-1, "上传数据库失败", false);
        }


    }

    /**
     *
     * @param path /music/get?path=***.mp3
     * @return
     */
    @RequestMapping("/get")
    public ResponseEntity<byte[]> get(String path) {
        /*byte[] a = {97, 98, 99, 100};
        //return ResponseEntity.internalServerError().build();//返回的状态码是500（这里，build，以符合返回类型）
        //return ResponseEntity.notFound().build();//返回的状态码是404（not found）
        return ResponseEntity.ok(a);//返回状态码的同时，也返回内容balabala*/
        File file = new File(SAVE_PATH + '/' + path);
        //↑↑↑注意这里边参数的含义
        System.out.println(file.getAbsoluteFile());
        byte[] a = null;
        try {
            a = Files.readAllBytes(file.toPath());//把音乐文件的内容存到二进制数组a中
            if(a == null){//读取失败（没有读取到）
                //return ResponseEntity.badRequest().body(null);
                return ResponseEntity.badRequest().build();//抛一个你认为的异常
            }
            return ResponseEntity.ok(a);
        }catch (IOException e){
            //
            e.printStackTrace();
        }
        return ResponseEntity.badRequest().build();
    }


    @RequestMapping("/delete")
    public ResponseBodyMessage<Boolean> deleteMusic(@RequestParam int id, HttpServletRequest request){
        //1.先检查：登陆了没
        HttpSession httpSession = request.getSession(false);//false:如果没有，不创建
                                                               //true:如果没有，创建
        if(httpSession == null || httpSession.getAttribute(Constant.USERINFO_SESSION_KEY)==null){//注意这一句的含义：httpSession.getAttribute(Constant.USERINFO_SESSION_KEY)==null
            System.out.println("删除失败，用户尚未登录");
            return new ResponseBodyMessage<>(-1,"删除失败，用户尚未登录",false);
        }
        /*参照 上传音乐模块
        //1.检查是否登录了
        HttpSession httpSession = request.getSession(false);
        if (httpSession == null || httpSession.getAttribute(Constant.USERINFO_SESSION_KEY) == null) {
            System.out.println("上传失败，用户尚未登录");
            return new ResponseBodyMessage<>(-1, "请先登录", false);
        }*/

        //2.查询数据库：有没有要删除的内容
        Music music = musicMapper.seleltByID(id);
        if (music == null) {
            System.out.println("要删除的内容不存在！");//找不到不用异常处理？？？或者说，select操作不用try-catch？
            return new ResponseBodyMessage<>(-1,"要删除的内容不存在",false);
        }
        //File file = new File(SAVE_PATH + '/' + music.getTitle() + ".mp3");//看似创建，其实是拿到这个文件
        //↑↑↑这里，好像不用这样？
        //但是，只是删除了数据库中的内容，并没有删除服务器中的。

        File file = new File(SAVE_PATH + '/' + music.getTitle() + ".mp3");//看似创建，其实是拿到这个文件
        file.delete();

        //3.删除，返回相应数据（成功/失败）
        int a = 0;
        a = musicMapper.deleteByID(id);
        //同步删除喜欢表中的音乐
        loveMusicMapper.deleteLoveMusicByMusicId(id);
        if (a != 1) {
            //删除失败
            System.out.println("删除失败！");
            return new ResponseBodyMessage<>(-1,"删除失败",false);
        }

        System.out.println("删除成功！");
        return new ResponseBodyMessage<>(0,"删除成功",true);

    }

    @RequestMapping("/deleteSel")//老师这里一开始没加/，postman测试也通过了
                                                    // ↓↓↓参数绑定
    public ResponseBodyMessage<Boolean> deleteMusics(@RequestParam("id[]") List<Integer> ids){//用数组来接收（多个id）
        //
        System.out.println("所有的id：" + ids);
        int sum = 0;
        for(Integer id : ids){
        //for(int i = 0; i < ids.size(); i++){
//            Music music = musicMapper.seleltByID(ids.get(i));//有没有
//            if (music != null) {
//                //数据库删除
//                int del = musicMapper.deleteByID(ids.get(i));
            Music music = musicMapper.seleltByID(id);//有没有
            if (music != null) {
                //数据库删除
                int del = musicMapper.deleteByID(id);
                //同步删除喜欢表中的这个音乐
                loveMusicMapper.deleteLoveMusicByMusicId(id);
                if(del != 1){
                    System.out.println("数据库删除失败！");
                    continue;
                }

                //服务器删除
                File file = new File(SAVE_PATH + '/' + music.getTitle() + ".mp3");
                 if(file.delete()) sum += 1;
                 else System.out.println("服务器删除失败！");
            }else {
                System.out.println("要删除的id为" + id + "的音乐不存在！");
                return new ResponseBodyMessage<>(-1,"没有你要删除的音乐！",false);
            }
        }

        if(sum == ids.size()){
            return new ResponseBodyMessage<>(1,"整体删除成功！",true);
        }else{
            return new ResponseBodyMessage<>(-1,"整体删除失败",false);
        }
    }

    @RequestMapping("/findmusic")
                              //泛型参数——用到了List，因为返回的可能不止一个
                                                    //@RequestParam——用于绑定
    public ResponseBodyMessage<List<Music>> findMusic(@RequestParam(required = false) String musicName){//required = false——表示：可以不传参数
        List<Music> musicList = null;
        if(musicName != null){
            musicList = musicMapper.findMusicByName(musicName);
            return new ResponseBodyMessage<>(0,"按音乐名查询成功",musicList);
        }else{
            musicList = musicMapper.findMusic();
            return new ResponseBodyMessage<>(0,"查询所有音乐成功",musicList);
        }
        //其实可以把返回操作放在这里。
    }
}